package com.a0soft.gphone.aTruffleHog.JarMain;
/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 3, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * Copyright(C) 2011 
 *   Sam Lu <ysl.sam.lu (at) gmail.com>
 *
 */

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import com.a0soft.gphone.aTruffleHog.di.DeviceInfo;
import com.a0soft.gphone.aTruffleHog.di.DeviceInfoKey;
import com.a0soft.gphone.aTruffleHog.di.GoldenInfo;
import com.a0soft.gphone.aTruffleHog.srvc.HttpConnSrvc;
import com.a0soft.gphone.aTruffleHog.util.CrashHandler;
import com.a0soft.gphone.aTruffleHog.util.MiscUtil;
import com.a0soft.gphone.aTruffleHog.util.aDebug;

public class JarMain {
    private static BroadcastReceiver m_br;
    
    private static final String LOG_TAG = JarMain.class.getSimpleName();
    
    /**
     * throw IllegalArgumentException if HttpConnSrvc is not declared in AndroidManifest.xml 
     * 
     * @param ctx: activity context
     * @param strDeveloperEmail: developer email, used to send crash report email. null if you don't wan to enable the crash report email function
     * @param bShowSystemCrashDialog: also show system crash dialog when crashing, only be used when strDeveloperEmail specified
     */
    public static void
    Init(Context ctx, 
         String strDeveloperEmail, boolean bShowSystemCrashDialog)
    {
        MiscUtil.Init(ctx);
        CrashHandler.Init(ctx, strDeveloperEmail, bShowSystemCrashDialog);
        
        _InitDeviceInfo(ctx);
    }
    
    private static void
    _InitDeviceInfo(final Context ctx)
    {
        DeviceInfo di = DeviceInfo.GetInstance(ctx);
        
        if (!di.IsReady()) {
            di.Init(false, new DeviceInfo.OnListener() {            
                @Override public void 
                OnDeviceInfoReady(DeviceInfo di)
                {
                    if (aDebug.ENABLED)
                        aDebug.d(LOG_TAG, "OnDeviceInfoReady()");
                    
                    _OnDeviceInfoReady(ctx);
                }
            });
        }
        else {
            _OnDeviceInfoReady(ctx);
        }
    }
    
    private static void
    _OnDeviceInfoReady(Context ctx)
    {
        if (!GoldenInfo.GetInstance(ctx).IsGoldenChanged()) {
            if (aDebug.ENABLED)
                aDebug.d(LOG_TAG, "golden not changed, don't resend device info.");
            return;
        } 
        
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "golden changed, send device info.");

        _InitBroadcastReceiver();
        
        DeviceInfo di = DeviceInfo.GetInstance(ctx);
        StringBuilder sb = new StringBuilder(8192);
        di.ToJSONString(sb);
        
        HttpConnSrvc.RequestSendDeviceInformation(ctx, 
                di.GetString(DeviceInfoKey.K.UR_ID),
                sb.toString());
    }
    
    private static void
    _InitBroadcastReceiver()
    {
        m_br = new BroadcastReceiver() {            
            @Override public void 
            onReceive(Context ctx, Intent it)
            {
                if (it == null) return;
                final String strAction = it.getAction();
                if (strAction == null) return;
                
                if (aDebug.ENABLED)
                    aDebug.d(LOG_TAG, "strAction=" + strAction);
                
                if (strAction.equals(HttpConnSrvc.ACTION_DOWNLOAD_STATUS)) {
                    int nStatus = it.getIntExtra(HttpConnSrvc.EXTRA_DOWNLOAD_STATUS, 
                                                 HttpConnSrvc.DOWNLOAD_STATUS_UNKNOWN);
                    int nCmd = it.getIntExtra(HttpConnSrvc.EXTRA_CMD, 
                                              HttpConnSrvc.CMD_UNKNOWN);

                    String strResultOrError = it.getStringExtra(HttpConnSrvc.EXTRA_DOWNLOAD_CONTENT);

                    if (aDebug.ENABLED) {
                        aDebug.d(LOG_TAG, "  nCmd=" + nCmd);
                        aDebug.d(LOG_TAG, "  nStatus=" + nStatus);
                    }
                    
                    switch (nStatus) {
                    case HttpConnSrvc.DOWNLOAD_STATUS_START:
                        OnDownloadStart(nCmd);
                        break;
                    case HttpConnSrvc.DOWNLOAD_STATUS_FINISHED_OKAY:
                        OnDownloadFinishedOkay(nCmd, strResultOrError);
                        break;
                    case HttpConnSrvc.DOWNLOAD_STATUS_FINISHED_ERROR:
                        OnDownloadFinishedError(nCmd, strResultOrError);
                        break;   
                    case HttpConnSrvc.DOWNLOAD_STATUS_STOP:
                        OnDownloadStop(nCmd);
                        break;
                    }
                }
            }
        };
        
        IntentFilter itf = new IntentFilter(HttpConnSrvc.ACTION_DOWNLOAD_STATUS);
        MiscUtil.GetAppContext().registerReceiver(m_br, itf);
    }
    
    private static void 
    OnDownloadStart(int nCmd) 
    {
        if (nCmd != HttpConnSrvc.CMD_SEND_DEVICE_INFO) return;
        
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "OnDownloadStart()");
    }
    
    private static void 
    OnDownloadFinishedError(int nCmd, String strError) 
    {
        if (nCmd != HttpConnSrvc.CMD_SEND_DEVICE_INFO) return;
        
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "OnDownloadFinishedError()");
    }
    
    private static void 
    OnDownloadStop(int nCmd) 
    {
        if (nCmd != HttpConnSrvc.CMD_SEND_DEVICE_INFO) return;
        
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "OnDownloadStop()");
        
        //add try/catch for java.lang.IllegalArgumentException: Receiver not registered
        //it should not happen, no idea why we have this error for some users
        try {
            MiscUtil.GetAppContext().unregisterReceiver(m_br);
        } catch (Exception e) {}  
        m_br = null;
    }

    private static void 
    OnDownloadFinishedOkay(int nCmd, String strResult) 
    {
        if (nCmd != HttpConnSrvc.CMD_SEND_DEVICE_INFO) return;
        
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "OnDownloadFinishedOkay()");
        
        GoldenInfo.GetInstance(MiscUtil.GetAppContext()).UnsetGoldenChanged();
    } 
}
